package com.ruoyi.book.util;

import com.microsoft.cognitiveservices.speech.AudioDataStream;
import com.microsoft.cognitiveservices.speech.SpeechConfig;
import com.microsoft.cognitiveservices.speech.SpeechSynthesisResult;
import com.microsoft.cognitiveservices.speech.SpeechSynthesizer;
import com.ruoyi.common.config.RuoYiConfig;

import java.io.*;
import java.net.URL;
import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicLong;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <!-- ms speech-->
 *         <dependency>
 *             <groupId>com.microsoft.cognitiveservices.speech</groupId>
 *             <artifactId>client-sdk</artifactId>
 *             <version>1.27.0</version>
 *         </dependency>
 */
public class VoiceTool {
    // This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
    private static String speechKey = "d9ce4b9e3e644cc098fa3a64c91904ff";

    private static String speechRegion = "eastus";

    public static void main(String[] args) throws Exception {
         String text="";
         speech(text,System.currentTimeMillis()+".wav");
    }
    //两个目录，一个保存目录，一个返回用于显示的目录
    public static  String speech(String text,final String fname)throws Exception{
        SpeechConfig speechConfig = SpeechConfig.fromSubscription(speechKey, speechRegion);

        speechConfig.setSpeechSynthesisVoiceName("zh-CN-YunxiNeural");

        SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig);

        // Get text from the console and synthesize to the default speaker.
        // System.out.println("Enter some text that you want to speak >");
        //&nbsp;<p>
        text=htmlFilter(text);
        System.out.println(text);

        String folder="/mp3/";
        //folder= RuoYiConfig.getUploadPath()+folder;
        folder= "d:/temp"+folder;
        File file = new File(folder);
        if(!file.exists())
            file.mkdirs();

        String savepath=folder+fname;
        System.out.println(savepath);
        //System.out.println(trn+">>>>>>>>>>");
        List<String> files=new ArrayList<>();
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, null);

        int index=0;
        int maxwords=1000;
        while (true){
            if(text.length()<=maxwords)
                maxwords=text.length();
            String tp=text.substring(0,maxwords);
            text=text.substring(maxwords);
            if(tp.length()<=0)
                break;

            SpeechSynthesisResult result = synthesizer.SpeakText(tp);
            AudioDataStream stream = AudioDataStream.fromResult(result);
            stream.saveToWavFile(savepath+(++index));//生成位置
            stream.close();
            files.add(savepath+index);

        }
        mergeWavVoice(new File("D:\\temp\\mp3\\1.wav"),files);
        return null;
        //return "/upload/mp3/"+fname;
    }


    public static void mergeWavVoice(File file, List<String> inputStreamList) {
        System.out.println(">>>>开始合并处理<<<<");
        List<AudioInputStream> audioInputStreams = new LinkedList<>();
        AtomicLong allLength = new AtomicLong(0L);
        try {
            inputStreamList.forEach(filePath -> {
                try {
                    String bath = filePath.split(":")[0];
                    AudioInputStream ais;
                    // 通过授权url获取音频输入流
                    if ("HTTP".equalsIgnoreCase(bath) || "HTTPS".equalsIgnoreCase(bath)) {
                        ais = AudioSystem.getAudioInputStream(new URL(filePath));
                    } else {
                        ais = AudioSystem.getAudioInputStream(new File(filePath));
                    }
                    allLength.addAndGet(ais.getFrameLength());
                    audioInputStreams.add(ais);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("获取wav文件异常!");
                }
            });
            // LinkedList需要迭代器装入Enumeration，才能放入SequenceInputStream
            Enumeration<AudioInputStream> enumeration = Collections.enumeration(audioInputStreams);
            // 合并音频输入流
            SequenceInputStream sequenceInputStream = new SequenceInputStream(enumeration);
            // 构造在示例帧中具有需要格式和长度的音频输入流
            AudioInputStream finalAudioInputStream = new AudioInputStream(sequenceInputStream,
                    audioInputStreams.get(0).getFormat(), allLength.get());
            // 输出音频流
            AudioSystem.write(finalAudioInputStream, AudioFileFormat.Type.WAVE, file);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static String htmlFilter(String htmlStr) {
        // 定义script的正则表达式
        String regExScript = "<script[^>]*?>[\\s\\S]*?</script>";
        // 定义style的正则表达式
        String regExStyle = "<style[^>]*?>[\\s\\S]*?</style>";
        // 定义HTML标签的正则表达式
        String regExHtml = "<[^>]+>";

        // 过滤script标签
        Pattern pScript = Pattern.compile(regExScript, Pattern.CASE_INSENSITIVE);
        Matcher mScript = pScript.matcher(htmlStr);
        htmlStr = mScript.replaceAll("");

        Pattern pStyle = Pattern.compile(regExStyle, Pattern.CASE_INSENSITIVE);
        Matcher mStyle = pStyle.matcher(htmlStr);
        htmlStr = mStyle.replaceAll("");

        Pattern pHtml = Pattern.compile(regExHtml, Pattern.CASE_INSENSITIVE);
        Matcher mHtml = pHtml.matcher(htmlStr);
        htmlStr = mHtml.replaceAll("");

        String str = htmlStr.trim();
        str = str.replaceAll("\\s*", "").replaceAll("", "");
        str = str.replaceAll("(&)*nbsp;*", "").replaceAll("", "");
        return str;
    }
}
